
#ifndef __WAITQUEUE_H__
#define __WAITQUEUE_H__

/** @file
 * Warteschlangen zum halten von Prozessen.
 */

#include "process.h"

/// Warteschlangentyp
typedef struct waitqueue_t {
    list process_list; ///< Liste der Prozesse in einer Warteschlange
} waitqueue_t;

/// globale Warteschlange mit allen laufen Prozessen, die auf CPU warten
extern waitqueue_t active_list;

/**
 * Initialisiert eine leere Warteschlange.
 *
 * @param wq : die Warteschlange
 * @return Zeiger auf gegebene Warteschlange
 */
waitqueue_t *wq_init(waitqueue_t *wq);

/**
 * Fügt einen Prozess an Anfang einer Warteschlange ein.
 *
 * @param wq : die Warteschlange
 * @param process : der Prozess
 *
 * @return Zeiger auf gegebene Warteschlange
 */
waitqueue_t *wq_push(waitqueue_t *wq, process_t *process);

/**
 * Fügt einen Prozess ans Ende einer Warteschlange ein.
 *
 * @param wq : die Warteschlange
 * @param process : der Prozess
 *
 * @return Zeiger auf gegebene Warteschlange
 */
waitqueue_t *wq_enqueue(waitqueue_t *wq, process_t *process);

/**
 * Entfernt ersten Eintrag aus der Warteschlange.
 *
 * @param wq : die Warteschlange
 * @return entfernter Prozess oder NULL, wenn Warteschlange leer war
 */
process_t *wq_pop(waitqueue_t *wq);

/**
 * Gibt ersten Eintrag aus der Warteschlange zurück. 
 * Prozess wird nicht entfernt
 *
 * @param wq : die Warteschlange
 * @return nächster Prozess oder NULL, wenn Warteschlange leer ist
 */
process_t *wq_peek(waitqueue_t *wq);

/**
 * Entfernt Prozess aus seiner Warteschlange.
 *
 * @param process : zu entfernender Prozess.
 */
void wq_dequeue(process_t *process);

/**
 * Entfernt Alle Prozess aus einer Warteschlange und fügt diese in zweite
 * Warteschlange ein
 *
 * @param dest : Warteschlange, in die Prozess eingefügt werden sollen.
 * @param src : Warteschlange, aus der Prozesse entfernt werden sollen.
 *
 * @return Zeiger auf Warteschlange dest
 */
waitqueue_t *wq_enqueue_all(waitqueue_t *dest, waitqueue_t *src);

#endif

